package br.com.infnet.formularioeletronico.dados;

import java.lang.reflect.Method;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public abstract class AbstractDAO<T> {

    protected abstract EntityManager getEntityManager();
    
    private Class<T> entityClass;
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("FormularioEletronicoPU");
    EntityManager em = emf.createEntityManager();
    EntityTransaction transaction = em.getTransaction();  
    
    public AbstractDAO(Class<T> entityClass) {
        this.entityClass = entityClass;
        this.transaction.begin();
    }

    @SuppressWarnings("rawtypes")
	public long incluir(T entity) {

        long retorno = 0;
        em.persist(entity);

        try {

            Class[] classes = new Class[0];
            Method metodo = entityClass.getMethod("getId", classes);
            if (metodo != null) {

                Object[] objetos = new Object[0];
                Long id = (Long) metodo.invoke(entity, objetos);
                if (id != null) {

                    retorno = id.longValue();
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            em.getTransaction().commit();
//            em.close();
//            emf.close();
        }
        return retorno;
    }

    public boolean alterar(T entity) {

    	boolean result = true;
    	
        try {
            em.merge(entity);
            em.getTransaction().commit();

        } catch (Exception e) {
        	result = false;
            e.printStackTrace();
        } finally {
//            em.close();
//            emf.close();
        }
        
        return result;
    }

    public void excluir(long id) {

        if (id > 0) {
            T entity = em.find(entityClass, id);
            try {

                if (entity != null) {
                    em.remove(entity);
                    em.getTransaction().commit();
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
//                em.close();
//                emf.close();
            }
        }
    }

    public T obter(long id) {
        T entity = null;
        try {
            if (id > 0) {
                entity = em.find(entityClass, id);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
//            em.close();
//            emf.close();
        }
        return entity;
    }

    public List<T> listar() {
        List<T> retorno = null;
        try {
            retorno = em.createQuery("select e from "
                    + entityClass.getSimpleName()
                    + " e").getResultList();
        } catch (Exception e) {
        } finally {

        }
        return retorno;

    }
    
    public List<T> listar(String strNomeCampo, String strValorCampo) {
        List<T> retorno = null;
        try {        	
            retorno = em.createQuery("select e from "
            		+ entityClass.getSimpleName()
            		+ " e where upper(e."
            		+ strNomeCampo
            		+ ") like '" + strValorCampo + "%'", entityClass).getResultList();
        } catch (Exception e) {
        } finally {

        }
        return retorno;

    }
    
}
